package com.zzyl.intercept;

import cn.hutool.core.text.AntPathMatcher;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.zzyl.constant.Constants;
import com.zzyl.constant.UserCacheConstant;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.properties.JwtProperties;
import com.zzyl.utils.JwtUtil;
import com.zzyl.utils.StringUtils;
import com.zzyl.utils.UserThreadLocal;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@Component
@Slf4j
public class AdminInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //如果不是映射到方法就放行，比如跨域验证请求、静态资源等不需要身份校验的请求
        if(!(handler instanceof HandlerMethod)){
            return true;
        }

        //获取请求的路径
        String requestURI = request.getRequestURI();
        log.info("拦截后台请求路径接口={}",requestURI);

        //获取到token
        String token = request.getHeader(Constants.ADMIN_TOKEN);
        if (StringUtils.isEmpty(token)) {
            //未登录
            throw new BaseException(BasicEnum.LOGIN_FAIL);
        }

            //解析token
            Claims claims = JwtUtil.parseJWT(jwtProperties.getBase64EncodedSecretKey(), token);
            if (claims == null) {
                throw new BaseException(BasicEnum.LOGIN_FAIL);
            }
            String userId = claims.get(Constants.JWT_USERID).toString();

            //获取redis中的key
            String key = UserCacheConstant.PUBLIC_ACCESS_URLS + userId;
            //从redis中读取数据
            String result = redisTemplate.opsForValue().get(key);

            List<String> resourcePaths = null;
            //将json字符串转换为集合
            if (!StringUtils.isEmpty(result)) {
                 resourcePaths = JSONUtil.toList(result, String.class);
            }

            //获取当前请求的资源路径
            String requestUrl = request.getMethod() + requestURI;
            for (String url : resourcePaths) {
                //判断请求路径是否符合权限
                if (antPathMatcher.match(url,requestUrl)) {

                    //将当前登录用户ID存入当前请求线程ThreadLocal中
                    UserThreadLocal.set(Long.valueOf(userId));
                    //放行
                    return true;
                }
            }

            //否则没有权限
            throw new BaseException(BasicEnum.SECURITY_ACCESSDENIED_FAIL);

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //请求结束清除线程中的数据
        UserThreadLocal.remove();
    }
}
